package com.tianxiao.faas.biz.service.corner;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.tianxiao.faas.api.param.corner.*;
import com.tianxiao.faas.biz.domain.entity.GoodsValueBox;
import com.tianxiao.faas.biz.domain.entity.ShopValueBox;
import com.tianxiao.faas.common.exception.biz.BizException;
import com.tianxiao.faas.common.util.PageUtils;
import com.tianxiao.faas.mapper.dao.GoodsModelMapper;
import com.tianxiao.faas.mapper.dao.RankingModelMapper;
import com.tianxiao.faas.mapper.dao.ShopModelMapper;
import com.tianxiao.faas.mapper.model.GoodsModel;
import com.tianxiao.faas.mapper.model.RankingModel;
import com.tianxiao.faas.mapper.model.ShopModel;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class RankingService {

    @Resource
    private RankingModelMapper rankingModelMapper;

    @Resource
    private ShopModelMapper shopModelMapper;

    @Resource
    private GoodsModelMapper goodsModelMapper;

    public List<RankingGoodsResult> goodsList(BasePageParam param, Integer type) {
        List<RankingModel> list = rankingModelMapper.list(type, 0L, PageUtils.getOffset(param.getPage(), param.getPageSize()), param.getPageSize());
        if (CollectionUtils.isEmpty(list)) {
            return Lists.newArrayList();
        }
        List<RankingGoodsResult> rankingGoodsResults = new ArrayList<>();
        List<Long> goodsIds = list.stream().map(RankingModel::getObject).collect(Collectors.toList());
        List<GoodsModel> goodsModels = goodsModelMapper.queryByIds(goodsIds);
        if (CollectionUtils.isEmpty(goodsModels)) {
            return Lists.newArrayList();
        }
        Map<Long, GoodsModel> goodsModelMap = goodsModels.stream().collect(Collectors.toMap(GoodsModel::getId, s -> s));
        for (RankingModel rankingModel : list) {
            GoodsModel goodsModel = goodsModelMap.get(rankingModel.getObject());
            RankingGoodsResult rankingGoodsResult = getGoodsListResult(rankingModel, goodsModel);
            if (rankingGoodsResult != null) {
                rankingGoodsResults.add(rankingGoodsResult);
            }
        }
        return rankingGoodsResults;
    }

    public List<RankingShopResult> shopList(RankingShopListPageParam param, Integer type) {
        Long categoryId = param.getCategoryId();
        List<RankingModel> list = rankingModelMapper.list(type, categoryId, PageUtils.getOffset(param.getPage(), param.getPageSize()), param.getPageSize());
        if (CollectionUtils.isEmpty(list)) {
            return Lists.newArrayList();
        }
        List<RankingShopResult> rankingShopResults = new ArrayList<>();
        List<Long> shopIds = list.stream().map(RankingModel::getObject).collect(Collectors.toList());
        List<ShopModel> shopModels = shopModelMapper.queryByIds(shopIds);
        if (CollectionUtils.isEmpty(shopModels)) {
            return Lists.newArrayList();
        }
        Map<Long, ShopModel> shopModelMap = shopModels.stream().collect(Collectors.toMap(ShopModel::getId, s -> s));
        for (RankingModel rankingModel : list) {
            ShopModel shopModel = shopModelMap.get(rankingModel.getObject());
            RankingShopResult rankingShopResult = getShopListResult(rankingModel, shopModel);
            if (rankingShopResult != null) {
                rankingShopResults.add(rankingShopResult);
            }
        }
        return rankingShopResults;
    }

    public Integer count(Integer type) {
        Integer count = rankingModelMapper.count(type);
        return count == null ? 0 : count;
    }

    private RankingGoodsResult getGoodsListResult(RankingModel rankingModel, GoodsModel goodsModel) {
        if (goodsModel == null) {
            return null;
        }
        RankingGoodsResult rankingGoodsResult = new RankingGoodsResult();
        String valueBox = rankingModel.getValueBox();
        if (StringUtils.isNotBlank(valueBox)) {
            GoodsValueBox goodsValueBox = JSON.parseObject(valueBox, GoodsValueBox.class);
            rankingGoodsResult.setShopName(goodsValueBox.getShopName());
        }
        rankingGoodsResult.setId(rankingModel.getId());
        rankingGoodsResult.setName(goodsModel.getName());
        rankingGoodsResult.setGoodsId(rankingModel.getObject());
        rankingGoodsResult.setRecommendTxt(goodsModel.getRecommend());
        rankingGoodsResult.setImages(goodsModel.getImages());
        rankingGoodsResult.setInfo(goodsModel.getInfo());
        Long price = goodsModel.getPrice();
        price = price == null ? 0 : price;
        rankingGoodsResult.setPrice(new BigDecimal(price / 100).doubleValue());
        rankingGoodsResult.setShopId(goodsModel.getShopId());
        return rankingGoodsResult;
    }

    private RankingShopResult getShopListResult(RankingModel rankingModel, ShopModel shopModel) {
        if (shopModel == null) {
            return null;
        }
        RankingShopResult rankingShopResult = new RankingShopResult();
        rankingShopResult.setPoiAddress(shopModel.getPoi());
        rankingShopResult.setPerCapitaConsumption(shopModel.getPerCapitaConsumption());
        rankingShopResult.setId(rankingModel.getId());
        rankingShopResult.setName(shopModel.getName());
        rankingShopResult.setImages(shopModel.getImages());
        rankingShopResult.setRecommend(shopModel.getRecommend());
        rankingShopResult.setShopId(shopModel.getId());
        return rankingShopResult;
    }

    public void save(RankingSaveParam param) {
        RankingModel rankingModel = new RankingModel();
        long currentTimeMillis = System.currentTimeMillis();

        Integer type = param.getType();
        Long id = param.getId();

        rankingModel.setType(type);
        rankingModel.setCreated(currentTimeMillis);
        rankingModel.setUpdated(currentTimeMillis);
        rankingModel.setDeleted(0);
        Integer categoryId = param.getCategoryId();
        rankingModel.setCategoryId(categoryId);
        rankingModel.setObject(id);
        RankingModel byObjectIdAndType = rankingModelMapper.getByObjectIdAndType(id, type, null);
        if (byObjectIdAndType != null) {
            throw new BizException("榜单已存在该商品/门店");
        }
        if (type == 1) {
            ShopModel shopModel = shopModelMapper.selectByPrimaryKey(id);
            if (shopModel == null) {
                throw new BizException("是无效ID");
            }
            rankingModel.setImages(shopModel.getImages());
            rankingModel.setRecommend(shopModel.getRecommend());
            rankingModel.setName(shopModel.getName());
            rankingModel.setValueBox(getShopValueBox(shopModel));
        } else {
            GoodsModel goodsModel = goodsModelMapper.selectByPrimaryKey(id);
            if (goodsModel == null) {
                throw new BizException("是无效ID");
            }
            rankingModel.setImages(goodsModel.getImages());
            rankingModel.setRecommend(goodsModel.getRecommend());
            rankingModel.setName(goodsModel.getName());
            rankingModel.setValueBox(getGoodsValueBox(goodsModel));
        }
        rankingModelMapper.insertSelective(rankingModel);
    }

    private String getGoodsValueBox(GoodsModel goodsModel) {
        GoodsValueBox goodsValueBox = new GoodsValueBox();
        ShopModel shopModel = shopModelMapper.selectByPrimaryKey(goodsModel.getShopId());
        goodsValueBox.setShopName(shopModel.getName());
        return JSON.toJSONString(goodsValueBox);
    }

    private String getShopValueBox(ShopModel shopModel) {
        ShopValueBox shopValueBox = new ShopValueBox();
        shopValueBox.setPoiAddress(shopModel.getPoi());
        shopValueBox.setPerCapitaConsumption(shopModel.getPerCapitaConsumption());
        return JSON.toJSONString(shopValueBox);
    }

    public void delete(Long id) {
        long updated = System.currentTimeMillis();
        RankingModel rankingModel = new RankingModel();
        rankingModel.setId(id);
        rankingModel.setDeleted(1);
        rankingModel.setUpdated(updated);
        rankingModelMapper.updateByPrimaryKeySelective(rankingModel);
    }
}
